//
//  SceneHandler.cpp
//  cubemap
//
//  Created by AK on 2/1/12.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#include "SceneHandler.h"

SceneHandler::SceneHandler(){}

SceneHandler::~SceneHandler(){}


// Setup the window 
void SceneHandler::setupWindow(int pos_x, int pos_y, int width, int height, int argc, char * argv[], char *title)
{
    
    
    glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
	glutInitWindowPosition(pos_x, pos_y);
	glutInitWindowSize(width, height);
	glutCreateWindow(title);
    
    
}



// Setup the viewport and perspective projection for drawing
void SceneHandler::setupPerspectiveViewPort(int window_width, int window_height)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


    glViewport(0, 0, window_width, window_height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0f, (GLfloat)window_width/(GLfloat)window_height, 0.1f, 100.0f);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}

// Setup the viewport
void SceneHandler::setupViewPort(int window_width, int window_height)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    
    glMatrixMode( GL_PROJECTION );
    glPushMatrix();
    glLoadIdentity();
    glViewport(0, 0, window_width, window_height);
    
    glMatrixMode( GL_MODELVIEW );
    glPushMatrix();
    glLoadIdentity();

}

// Push the viewport
void SceneHandler::popViewPort()
{

    glMatrixMode( GL_PROJECTION );
    glPopMatrix();
    
    glMatrixMode( GL_MODELVIEW );
    glPopMatrix();
    
    glPopAttrib();

}


// Setup an orthological projection
void SceneHandler::setupOrthoProjection()
{

    glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho( -1, 1, -1, 1, 1.0, 40.0 );

}

/*
void SceneHandler::drawQuad(int width, int height)
{

    glBegin(GL_QUADS);
    glNormal3f(0.0, 0.0, 1.0);
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-1.0, 1.0, -1.0);
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(1.0, 1.0, -1.0);
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(1.0, -1.0, -1.0);
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(-1.0, -1.0, -1.0);
    glEnd();
     
     
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, height, 0.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(width, height, 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(width, 0.0f, 0.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f);
    glEnd();
}

*/
void SceneHandler::drawQuad()
{

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3d(-1, -1, 0);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3d(1, -1, 0);
    glTexCoord2f( 1.0f, 1.0f);
    glVertex3d(1, 1, 0);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3d(-1, 1, 0);
	glEnd();

}

void SceneHandler::drawSphere()
{


    float _radius        = 10.0f;
    
    int segs = 32;
    int dsegs = 2*segs;
    int i, j;
    float x, y, z, z1, z2, R, R1, R2;
    
    glPushMatrix();
    
    // Top cap
    glBegin(GL_TRIANGLE_FAN);
    glNormal3f(0,0,1);
    glTexCoord2f(0.5f,1.0f);
    glVertex3f(0,0,_radius);
    
    z = cos(M_PI/segs);
    R = sin(M_PI/segs);
    
    for (i = 0; i <= dsegs; i++)
    {
        x = R*cos(i*2.0*M_PI/(dsegs));
        y = R*sin(i*2.0*M_PI/(dsegs));
        
        glNormal3f(x, y, z);
        glTexCoord2f((float) i / (dsegs), 1.0f - 1.0f / segs);
        glVertex3f(_radius*x, _radius*y, _radius*z);
    }
    glEnd();
    
    // Height segments
    for (j = 1; j < segs-1; j++)
    {
        z1 = cos(j*M_PI/segs);
        R1 = sin(j*M_PI/segs);
        z2 = cos((j+1)*M_PI/segs);
        R2 = sin((j+1)*M_PI/segs);
        
        glBegin(GL_TRIANGLE_STRIP);
        
        for (i = 0; i <= 2*segs; i++)
        {
            x = R1*cos(i*2.0*M_PI/(dsegs));
            y = R1*sin(i*2.0*M_PI/(dsegs));
            
            glNormal3f(x, y, z1);
            glTexCoord2f((float) i/ (dsegs), 1.0f - (float) j / segs);
            glVertex3f(_radius*x, _radius*y, _radius*z1);
            
            x = R2*cos(i*2.0*M_PI/(dsegs));
            y = R2*sin(i*2.0*M_PI/(dsegs));
            
            glNormal3f(x, y, z2);
            glTexCoord2f((float) i / (dsegs), 1.0f - (float) (j + 1) / segs);
            glVertex3f(_radius*x, _radius*y, _radius*z2);
        }
        
        glEnd();
    }
    
    // Bottom cap
    glBegin(GL_TRIANGLE_FAN);
    
    glNormal3f(0,0,-1);
    glTexCoord2f(0.5f, 1.0f);
    glVertex3f(0,0,-_radius);
    
    z = -cos(M_PI/segs);
    R = sin(M_PI/segs);
    
    for ( i = dsegs; i >= 0; i--)
    {
        x = R*cos(i*2.0*M_PI/(dsegs));
        y = R*sin(i*2.0*M_PI/(dsegs));
        
        glNormal3f(x, y, z);
        glTexCoord2f(1.0f-(float)i/(dsegs), 1.0f/segs);
        glVertex3f(_radius*x, _radius*y, _radius*z);
    }
    
    glEnd();
    
    glPopMatrix();

    

}

// Draws a skybox with a cube map applied
void SceneHandler::drawSkyBox(GLuint environmentMap)
{

    float s = 5000.0f;
    
    static GLfloat sPlane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
    static GLfloat tPlane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
    static GLfloat rPlane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
    
    glActiveTexture(GL_TEXTURE0);
    glEnable (GL_TEXTURE_CUBE_MAP);
    glBindTexture(GL_TEXTURE_CUBE_MAP, environmentMap);
    
    glEnable (GL_TEXTURE_GEN_S);
    glEnable (GL_TEXTURE_GEN_T);
    glEnable (GL_TEXTURE_GEN_R);
    
    glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGeni (GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    
    glTexGenfv (GL_S, GL_OBJECT_PLANE, sPlane);
    glTexGenfv (GL_T, GL_OBJECT_PLANE, tPlane);
    glTexGenfv (GL_R, GL_OBJECT_PLANE, rPlane);
    
	// Draw a cube
	glBegin(GL_QUADS);
    glVertex3f(-s, -s, +s);
    glVertex3f(-s, +s, +s);
    glVertex3f(+s, +s, +s);
    glVertex3f(+s, -s, +s);
    
    glVertex3f(+s, -s, -s);
    glVertex3f(+s, -s, +s);
    glVertex3f(+s, +s, +s);
    glVertex3f(+s, +s, -s);
    
    glVertex3f(-s, -s, -s);
    glVertex3f(-s, +s, -s);
    glVertex3f(-s, +s, +s);
    glVertex3f(-s, -s, +s);
    
    glVertex3f(-s, +s, -s);
    glVertex3f(+s, +s, -s);
    glVertex3f(+s, +s, +s);
    glVertex3f(-s, +s, +s);
    
    glVertex3f(-s, -s, -s);
    glVertex3f(-s, -s, +s);
    glVertex3f(+s, -s, +s);
    glVertex3f(+s, -s, -s);
    
    glVertex3f(-s, -s, -s);
    glVertex3f(+s, -s, -s);
    glVertex3f(+s, +s, -s);
    glVertex3f(-s, +s, -s);
	glEnd();
    
    glDisable (GL_TEXTURE_CUBE_MAP);
    glDisable (GL_TEXTURE_GEN_S);
    glDisable (GL_TEXTURE_GEN_T);
    glDisable (GL_TEXTURE_GEN_R);
    
    glBindTexture (GL_TEXTURE_CUBE_MAP, 0);


}